//
//  NSArray+YQJExtesionSignal.m
//  Yiqijiao
//
//  Created by fengxijun on 3/11/16.
//  Copyright © 2016 yiqijiao. All rights reserved.
//

#import "NSArray+YQJExtesionSignal.h"
#import <objc/runtime.h>

@implementation NSArray (YQJExtesionSignal)

- (RACSignal *)formatDataSignalWithClass:(Class)cls
{
    
    __block RACSequence __weak *sequence = [self rac_sequence];
    RACSignal *signal = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
        
        [subscriber sendNext:[[[sequence filter:^BOOL(id value) {
            return [value isKindOfClass:[NSDictionary class]];
        }] map:^id(NSDictionary *dictionary) {
            id obj = [[cls alloc] init];
            [obj setValuesForKeysWithDictionary:dictionary];
            return obj;
        }] array]];
        [subscriber sendCompleted];
        
        return [RACDisposable disposableWithBlock:^{
            nil;
        }];
    }];
    
    return signal;
}

-(NSArray *)formatDataToClass:(Class)cls
{
    RACSequence *sequence = [self rac_sequence];
    return [[[sequence filter:^BOOL(id value) {
        return [value isKindOfClass:[NSDictionary class]];
    }] map:^id(NSDictionary *dictionary) {
        id obj = [[cls alloc] init];
        [obj setValuesForKeysWithDictionary:dictionary];
        return obj;
    }] array];
}

@end

@implementation NSMutableArray (YQJExtesionSignal)

- (RACSignal *)valueChangedSignal
{
    RACSignal *signal = objc_getAssociatedObject(self, _cmd);
    if (signal == nil) {
        @weakify(self)
        RACSignal *addObjectSignal = [[self rac_signalForSelector:@selector(addObject:)] map:^id(RACTuple *tuple) {
            @strongify(self)
            return self;
        }];
        RACSignal *insertObjectSignal = [[self rac_signalForSelector:@selector(insertObject:atIndex:)] map:^id(RACTuple *tuple) {
            @strongify(self)
            return self;
        }];
        RACSignal *removeLastObjectSignal = [[self rac_signalForSelector:@selector(removeLastObject)] map:^id(RACTuple *tuple) {
            @strongify(self)
            return self;
        }];
        
        RACSignal *removeObjectAtIndexSignal = [[self rac_signalForSelector:@selector(removeObjectAtIndex:)] map:^id(RACTuple *tuple) {
            @strongify(self)
            return self;
        }];
        
        RACSignal *replaceObjectAtIndexSignal = [[self rac_signalForSelector:@selector(replaceObjectAtIndex:withObject:)] map:^id(RACTuple *tuple) {
            @strongify(self)
            return self;
        }];
        
        RACSignal *addObjectsFromArraySignal = [[self rac_signalForSelector:@selector(addObjectsFromArray:)] map:^id(RACTuple *tuple) {
            @strongify(self)
            return self;
        }];
        
        RACSignal *exchangeObjectAtIndexSignal = [[self rac_signalForSelector:@selector(exchangeObjectAtIndex:withObjectAtIndex:)] map:^id(RACTuple *tuple) {
            @strongify(self)
            return self;
        }];
        
        RACSignal *removeAllObjectsSignal = [[self rac_signalForSelector:@selector(removeAllObjects)] map:^id(RACTuple *tuple) {
            @strongify(self)
            return self;
        }];
        
        RACSignal *removeObjectInRangeSignal = [[self rac_signalForSelector:@selector(removeObject:inRange:)] map:^id(RACTuple *tuple) {
            @strongify(self)
            return self;
        }];
        
        //        - (void)sortUsingFunction:(NSInteger (*)(ObjectType,  ObjectType, void * __nullable))compare context:(nullable void *)context;
        //        - (void)sortUsingSelector:(SEL)comparator;
        //
        //        - (void)insertObjects:(NSArray<ObjectType> *)objects atIndexes:(NSIndexSet *)indexes;
        //        - (void)removeObjectsAtIndexes:(NSIndexSet *)indexes;
        //        - (void)replaceObjectsAtIndexes:(NSIndexSet *)indexes withObjects:(NSArray<ObjectType> *)objects;
        //
        //        - (void)setObject:(ObjectType)obj atIndexedSubscript:(NSUInteger)idx NS_AVAILABLE(10_8, 6_0);
        //
        //        - (void)sortUsingComparator:(NSComparator)cmptr NS_AVAILABLE(10_6, 4_0);
        //        - (void)sortWithOptions:(NSSortOptions)opts usingComparator:(NSComparator)cmptr NS_AVAILABLE(10_6, 4_0);
        
        RACSignal *removeObjectSignal = [[self rac_signalForSelector:@selector(removeObject:)] map:^id(RACTuple *tuple) {
            @strongify(self)
            return self;
        }];
        
        RACSignal *removeObjectIdenticalToSignal = [[self rac_signalForSelector:@selector(removeObjectIdenticalTo:)] map:^id(RACTuple *tuple) {
            @strongify(self)
            return self;
        }];
        
        RACSignal *removeObjectIdenticalToInRangeSignal = [[self rac_signalForSelector:@selector(removeObjectIdenticalTo:inRange:)] map:^id(RACTuple *tuple) {
            @strongify(self)
            return self;
        }];
        
        RACSignal *removeObjectsFromIndicesSignal = [[self rac_signalForSelector:@selector(removeObjectsFromIndices:numIndices:)] map:^id(RACTuple *tuple) {
            @strongify(self)
            return self;
        }];
        
        RACSignal *removeObjectsInArraySignal = [[self rac_signalForSelector:@selector(removeObjectsInArray:)] map:^id(RACTuple *tuple) {
            @strongify(self)
            return self;
        }];
        
        RACSignal *removeObjectsInRangeSignal = [[self rac_signalForSelector:@selector(removeObjectsInRange:)] map:^id(RACTuple *tuple) {
            @strongify(self)
            return self;
        }];
        
        RACSignal *replaceObjectsInRangeFromArraySignal = [[self rac_signalForSelector:@selector(replaceObjectsInRange:withObjectsFromArray:range:)] map:^id(RACTuple *tuple) {
            @strongify(self)
            return self;
        }];
        
        RACSignal *replaceObjectsInRangeOtherArraySignal = [[self rac_signalForSelector:@selector(replaceObjectsInRange:withObjectsFromArray:)] map:^id(RACTuple *tuple) {
            @strongify(self)
            return self;
        }];
        
        RACSignal *replaceObjectsInRangeOtherArrayCountSignal = [[self rac_signalForSelector:@selector(replaceObjectsInRange:withObjects:count:)] map:^id(RACTuple *tuple) {
            @strongify(self)
            return self;
        }];
        
        RACSignal *setArraySignal = [[self rac_signalForSelector:@selector(setArray:)] map:^id(RACTuple *tuple) {
            @strongify(self)
            return self;
        }];
        
        signal = [RACSignal merge:@[addObjectSignal,insertObjectSignal,removeLastObjectSignal,removeObjectAtIndexSignal,replaceObjectAtIndexSignal,addObjectsFromArraySignal,exchangeObjectAtIndexSignal,removeAllObjectsSignal,removeObjectInRangeSignal,removeObjectSignal,removeObjectIdenticalToSignal,removeObjectIdenticalToInRangeSignal,removeObjectsFromIndicesSignal,removeObjectsInArraySignal,removeObjectsInRangeSignal,replaceObjectsInRangeFromArraySignal,replaceObjectsInRangeOtherArraySignal,replaceObjectsInRangeOtherArrayCountSignal,setArraySignal]];
        
        objc_setAssociatedObject(self, _cmd, signal, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    return signal;
    
}

@end
